package com.starrocks.entity;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.annotation.JSONField;
import com.alibaba.fastjson2.TypeReference;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

/**
 * 目标表配置实体
 * 一个源表可以同步到多个目标表（一对多）
 */
@Slf4j
@Data
@TableName("sync_target")
public class SyncTargetEntity {
    
    /**
     * 主键ID
     */
    @TableId(type = IdType.AUTO)
    private Long id;
    
    /**
     * 关联的sync_config.id
     */
    private Long configId;
    
    /**
     * TiDB目标表名
     */
    private String targetTableName;
    
    /**
     * 目标表主键字段名（为空则使用源表主键）
     */
    private String targetPrimaryKey;
    
    /**
     * 是否使用目标表自己的ID（默认false，使用源表ID）
     */
    private Boolean useTargetId;
    
    /**
     * ID生成策略：AUTO_INCREMENT（自增）、UUID、SNOWFLAKE
     * 仅当useTargetId=true时有效
     */
    private String idGenerateStrategy;
    
    /**
     * 是否使用软删除（默认false，即物理删除）
     * 如果为false，当检测到源表数据被软删除时，会物理删除目标表对应数据
     */
    private Boolean useSoftDelete;
    
    /**
     * 需要同步的字段列表（JSON数组字符串）
     * 示例: ["device_id", "device_name", "device_ip"]
     */
    private String syncFields;
    
    /**
     * 字段映射配置（JSON对象字符串）
     * 示例: {"device_id": "id", "device_name": "name"}
     */
    private String fieldMapping;
    
    /**
     * 是否启用：0-禁用，1-启用
     */
    private Boolean enabled;
    
    /**
     * 同步顺序（数字越小越先执行）
     */
    private Integer sortOrder;
    
    /**
     * 创建时间
     */
    private LocalDateTime createdTime;
    
    /**
     * 更新时间
     */
    private LocalDateTime updatedTime;
    
    // ========== 辅助方法：JSON 字段解析 ==========
    
    /**
     * 获取同步字段列表
     * @return 字段列表，如果为空返回 null
     */
    public List<String> getSyncFieldsList() {
        if (syncFields == null || syncFields.trim().isEmpty()) {
            return null;
        }
        try {
            return JSON.parseArray(syncFields, String.class);
        } catch (Exception e) {
            return null;
        }
    }
    
    /**
     * 设置同步字段列表（禁止在 JSON 反序列化时调用，避免覆盖 syncFields）
     * @param fields 字段列表
     */
    @JSONField(deserialize = false)  // 禁止反序列化时调用此方法
    public void setSyncFieldsList(List<String> fields) {
        if (fields == null || fields.isEmpty()) {
            this.syncFields = null;
        } else {
            this.syncFields = JSON.toJSONString(fields);
        }
    }
    
    /**
     * 获取字段映射Map
     * @return 字段映射，如果为空返回 null
     */
    public Map<String, String> getFieldMappingMap() {
        if (fieldMapping == null || fieldMapping.trim().isEmpty()) {
            return null;
        }
        try {
            return JSON.parseObject(fieldMapping, new TypeReference<Map<String, String>>() {});
        } catch (Exception e) {
            return null;
        }
    }
    
    /**
     * 设置字段映射Map（禁止在 JSON 反序列化时调用，避免覆盖 fieldMapping）
     * 注意：前端应该只发送 fieldMapping 字符串，不应发送 fieldMappingMap
     * @param mapping 字段映射
     */
    @JSONField(deserialize = false)  // 禁止反序列化时调用此方法
    public void setFieldMappingMap(Map<String, String> mapping) {
        // 该方法不应该被 JSON 反序列化调用
        // 如果被调用，说明前端错误地发送了 fieldMappingMap 字段
        log.warn("⚠️ setFieldMappingMap() 被调用，这可能导致数据不一致！fieldMappingMap 应该由 getFieldMappingMap() 自动生成");
        
        if (mapping == null || mapping.isEmpty()) {
            this.fieldMapping = null;
        } else {
            this.fieldMapping = JSON.toJSONString(mapping);
        }
    }
}

